--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Node / ReticulumProjects / MeshChatX.git / files / docs / agents / skills / meshchat-orchestration-split / SKILL.md
Displaying Raw • View rendered • Download
docs/agents/skills/meshchat-orchestration-split/SKILL.md dev (af76f09d) Text, 3.54 KB
Tc9d1d9# Skill: meshchat-orchestration-split
Extract or split HTTP routes and WebSocket handlers under Ta5d6ff`meshchatx/src/backend/http/`
without changing behaviour.
Tc9d1d9## When to use
Tff7b72- Splitting or moving handlers among Ta5d6ff`routes/<domain>.py` modules
Tff7b72- Moving WS inbound dispatch pieces among Ta5d6ff`ws/handlers_*.py`
Tff7b72- Adding new HTTP endpoints or WS message types in the extracted layout
Also read:
Tff7b72- Ta5d6ff`docs/agents/module-ownership.md`
Tff7b72- Ta5d6ff`docs/agents/conventions/backend.md`
Tff7b72- Ta5d6ff`docs/agents/conventions/tests.md`
Tc9d1d9## Hard rules
Tff7b721. Mechanical extract only. No renames, no error-map tweaks, no new logging in the same change as a move.
Tff7b722. One concern per change: move or behaviour, never both.
Tff7b723. Keep public entrypoints:
Tff7b72- Ta5d6ff`from meshchatx.meshchat import ReticulumMeshChat, main`
Tff7b72- Ta5d6ff`get_routes()` and Ta5d6ff`_define_routes(routes)` return shape
Tff7b72- middleware order: Ta5d6ff`auth`, Ta5d6ff`mime_type`, Ta5d6ff`security`, Ta5d6ff`csrf`, Ta5d6ff`ip_allowlist`
Tff7b724. Handlers use Ta5d6ff`app` where the original used Ta5d6ff`self`.
Tff7b725. No new business logic in route modules. Parse, call manager or app method, return response.
Tff7b726. Identity lifecycle and LXMF callbacks stay on Ta5d6ff`ReticulumMeshChat` until lifecycle packaging.
Tff7b727. Follow inventory names in Ta5d6ff`docs/agents/module-ownership.md`. Do not invent alternate folders.
Tff7b728. Domain splits start from existing Ta5d6ff`routes/<domain>.py` modules or residual shared helpers.
Do not re-extract routes from Ta5d6ff`meshchat.py`.
Tff7b729. One-shot extract scripts that rewrote Ta5d6ff`meshchat.py` were removed. Do not revive them.
Tc9d1d9## Layout
Current:
Ta5d6ff```
meshchatx/src/backend/http/
context.py
errors.py
live_names.py
meshchat_names.py
middleware.py
register.py
routes/<domain>.py
routes/__init__.py
ws/dispatch.py
ws/handlers_*.py
```
Pattern:
Ta5d6ff```Ta5d6ffpython
Tff7b72def Td2a8ffregister_status_routesTb4b4b4(Te6edf3routesTb4b4b4, Te6edf3appTb4b4b4)Tb4b4b4:
Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/statusTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffstatusTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72.Tff7b72.Tff7b72.
Ta5d6ff```
Ta5d6ff`register.py` calls Ta5d6ff`register_extracted_routes`, which binds meshchat free names via
Ta5d6ff`live_names.inject_meshchat_names` so Ta5d6ff`patch("meshchatx.meshchat.<symbol>")` still applies.
Lazy-import Ta5d6ff`register_all_routes` from inside Ta5d6ff`_define_routes` so route modules load after
meshchat is initialized.
Tc9d1d9## Contract scanners
Scanners must cover:
Tff7b72- Ta5d6ff`meshchatx/meshchat.py`
Tff7b72- Ta5d6ff`meshchatx/src/backend/http/**/*.py`
Tff7b72- lifecycle modules for broadcast payloads where relevant
HTTP: Ta5d6ff`tests/backend/http_api_contract_helpers.py` (Ta5d6ff`extract_meshchat_http_routes`).
WS: Ta5d6ff`tests/backend/ws_contract_helpers.py` (inbound, direct responses, broadcast).
Update fixtures only when inventory intentionally changes:
Ta5d6ff```Ta5d6ffbash
Te6edf3UPDATE_HTTP_API_ROUTESTff7b72=T79c0ff1 uv run pytest tests/backend/test_http_api_contract.py -k meshchat_http_routes_match_fixture
Te6edf3UPDATE_WS_MESSAGE_MANIFESTTff7b72=T79c0ff1 uv run pytest tests/backend/test_ws_json_contracts.py -k manifest_matches_meshchat
Ta5d6ff```
Tc9d1d9## Verification
After each domain move:
Ta5d6ff```Ta5d6ffbash
uv run pytest tests/backend/test_http_api_contract.py Tffea00\
tests/backend/test_api_json_contracts.py Tffea00\
tests/backend/test_http_api_json_contracts_broad.py Tffea00\
tests/backend/test_ws_json_contracts.py -q --tbTff7b72=short
Ta5d6ff```
Also run domain tests for the moved area and Ta5d6ff`task test:quick` at milestones.
Before declaring a large milestone done: Ta5d6ff`task test:backend` and Ta5d6ff`task test:frontend`.
Tc9d1d9## Compatibility patches
Tests often use Ta5d6ff`patch("meshchatx.meshchat.<symbol>")`. Keep those symbols importable from
Ta5d6ff`meshchatx.meshchat` (re-export if moved). Live name proxies live in Ta5d6ff`backend/http/live_names.py`.
Ta5d6ff`ReticulumMeshChat.on_websocket_data_received` is a one-line delegate to Ta5d6ff`http/ws/dispatch.py`.
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────